#include "catalog.h"
#include "query.h"
#include "index.h"
#include <string.h>
#include <stdlib.h>

/*
 * Inserts a record into the specified relation.
 *
 * Returns:
 * 	OK on success
 * 	an error code otherwise
 */

Status Updates::Insert(const string & relation, 
        const int attrCnt, 
        const attrInfo attrList[])
{

    Status status;
    int aCount;
    AttrDesc * relattrs;
    Record record;
    HeapFile * relHeap;
    RID newRid;
    bool attrFound = false;

    record.length = 0;

    status = attrCat->getRelInfo(relation, aCount, relattrs);

    if(status != OK)
        return status;

    //Calculate total length of record for memory allocation
    for(int i = 0; i < aCount; i++)
    {
        record.length += relattrs[i].attrLen;
    }

    record.data = malloc(record.length);

    if(!record.data)
    	return INSUFMEM;

    //Copy over the attributes into the record
    for(int i = 0; i < aCount; i++)
    {
        bool repeatFlag = false;
        for(int j = 0; j < attrCnt; j++)
        {
            if(strcmp(attrList[j].relName, relattrs[i].relName) == 0 && 
                    strcmp(attrList[j].attrName, relattrs[i].attrName) == 0)
            {
                if (repeatFlag) {
                    free (record.data);
                    return DUPLATTR;
                }
                repeatFlag = true;
                if(attrList[j].attrType != relattrs[i].attrType)
                {
                    free (record.data);
                    return ATTRTYPEMISMATCH;
                }
                if (relattrs[i].attrLen < attrList[j].attrLen)
                {
                    free (record.data);
                    return ATTRTOOLONG;
                }
                memcpy(((char *)record.data)+relattrs[i].attrOffset, attrList[j].attrValue, relattrs[i].attrLen);
                attrFound = true;
                break;
            }

        }
        if(!attrFound)
            return NULLINPUT;

        attrFound = false;
    }

    //Insert the record into the relation heapfile
    relHeap = new HeapFile(relation, status);

    if(status != OK)
    {
        delete relHeap;
        return status;
    }

    status = relHeap->insertRecord(record, newRid);

    if(status != OK)
    {
        delete relHeap;
        return status;
    }
    
    //Insert the record ID into each index for the relation
    for(int i = 0; i < aCount; i++)
    {
        if(relattrs[i].indexed)
        {
            Index tempIndex(relation, relattrs[i].attrOffset,
                    relattrs[i].attrLen, 
                    (Datatype) relattrs[i].attrType, 0, status);

            if(status != OK)
            {
                delete relHeap;
                return status;
            }

            status = tempIndex.insertEntry((char *)record.data 
                    + relattrs[i].attrOffset, newRid);
            if(status != OK)
            {
                delete relHeap;
                return status;
            }
        }
    }

    delete relHeap;

    return OK;
}












